﻿using Common.DTO;
using Database.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Database.Repositories
{
    public class CharacterRepository : RepositoryBase<Character>, IRepository<CharacterDTO>
    {
        //private readonly Mapper _mapper;

        public CharacterRepository()
        {
            //_mapper = new Mapper();
        }

        public Guid Create(CharacterDTO dto)
        {
            var userAccountEntity = DbContext.UserAccountSet.FirstOrDefault(
                x => x.Id == dto.UserAccount.Id);
            if (userAccountEntity == null)
                throw new EntityDoesNotExistException("UserAccount does not exist!");

            var characterEntity = Mapper.Map(dto);
            var id = Guid.NewGuid();
            characterEntity.Id = id;
            characterEntity.UserAccount = userAccountEntity;

            DbContext.CharacterSet.Add(characterEntity);
            DbContext.SaveChanges();

            return id;
        }

        public CharacterDTO Read(Guid id)
        {
            try
            {
                return Mapper.Map(
                DbContext.CharacterSet.Single(x => x.Id.Equals(id)));
            }
            catch (Exception)
            {
                return null;
            }
        }

        public bool Update(CharacterDTO dto)
        {
            var characterEntity = DbContext.CharacterSet.FirstOrDefault(
                x => x.Id == dto.Id);
            if (characterEntity == null)
                return false;

            // TODO_OL: Update all rows

            return SaveChanges();
        }

        public bool Delete(Guid id)
        {
            var entity = DbContext.CharacterSet.FirstOrDefault(
                x => x.Id == id);
            if (entity == null)
                return false;

            if (!MarkEntityForDeletion(entity))
                return false;

            return SaveChanges();
        }

        public bool DeleteAll()
        {
            var allEntites = DbContext.CharacterSet.Select(x => x).ToList();
            allEntites.ForEach(delegate(Character entity)
            {
                MarkEntityForDeletion(entity);
            });
            return SaveChanges(allEntites.Count);
        }

        public override bool MarkEntityForDeletion(Character entity)
        {
            MarkEntityDependenciesForDeletion();
            DbContext.CharacterSet.Remove(entity);

            return true;
        }
    }
}
